package track2.newBayes;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.HashMap;
import java.util.Map;

import track2.context.Config;
import track2.data.DescriptionToken;
import track2.data.PurchaseKeywordToken;
import track2.data.QueryToken;
import track2.data.TitleToken;
import track2.data.UserProfile;
import track2.result.Result;
//import track2.newBayes.*;

/**
 * Doing test work for {@link IdClassifier}
 * 
 * @author yijia, lingjuan
 * 
 */
public class IdTestClassifier {

	/**
	 * Test function for Id naive bayes
	 * 
	 * @return Result
	 */
	public static Map<Integer, String> user;
	public static NaiveBayesFeatures featureNB;
	public static Map<Integer, String> query;
	//public static Map<Integer, String> description;

	public static Result test(IdFeatures feature, String testFilePath)
			throws IOException, ClassNotFoundException {
		Result result = new Result();
		result.resultScore = new double[Config.testInstanceNum];
//		user = new HashMap<Integer, String>();
//		user = UserProfile.getInstance().getMap();
//		query = new HashMap<Integer, String>();
//		query = QueryToken.getInstance().getMap();
//		description = new HashMap<Integer, String>();
//		description = DescriptionToken.getInstance().getMap();
//		File file = new File(Config.naiveBayesFeaturePath);
//		FileInputStream fs = new FileInputStream(file);
//		ObjectInputStream os = new ObjectInputStream(fs);
		//featureNB = (NaiveBayesFeatures) os.readObject();
		int index = 0;
		try {
			System.out.println("Id Naive Bayes begin test...");
			BufferedReader br = new BufferedReader(new FileReader(testFilePath));
			String line;
			while ((line = br.readLine()) != null) {
				if (index % 1000000 == 0)
					System.out.println(index);
				String[] paras = line.split("\\t");
				int adID = Integer.parseInt(paras[1]);
				int advertiserID = Integer.parseInt(paras[2]);
				int queryID = Integer.parseInt(paras[5]);
				int purchaseID = Integer.parseInt(paras[6]);
				int titleID = Integer.parseInt(paras[7]);
				int descriptionID = Integer.parseInt(paras[8]);
				int userID = Integer.parseInt(paras[9]);

				double[] prob = new double[2];// 0 is for click probability, 1
												// for unclick probability
				// prior probability
				prob[0] += Math.log(feature.click);
				prob[1] += Math.log((1 - feature.click));

				if ((adID >= 0 && adID < Config.adIdSize)){
					getClickProb("A", adID, feature, prob);
					
				}
				if ((advertiserID >= 0 && advertiserID < Config.advertiserIdSize)){
					getClickProb("Aer", advertiserID, feature, prob);
				}
				if ((queryID >= 0 && queryID < Config.queryIdSize)) {
					getClickProb("Q", queryID, feature, prob);
//					String res = query.get(queryID);
//					if (res != null) {
//						getMore(res, prob, "Q");
//						//getMore(res, prob, "Q");
//					}

				}
				if ((titleID >= 0 && titleID < Config.titleIdSize)){
					getClickProb("T", titleID, feature, prob);
//					String res = title.get(queryID);
//					if (res != null) {
//						getMore(res, prob, "T");
//						//getMore(res, prob, "Q");
//					}
				}
				if ((purchaseID >= 0 && purchaseID < Config.purchaseIdSize)) {
					getClickProb("P", purchaseID, feature, prob);
				}
				if ((descriptionID >= 0 && descriptionID < Config.descriptionIdSize)){
					getClickProb("D", descriptionID, feature, prob);
//					String res = description.get(userID);
//					if (res != null) {
//						getMore(res, prob, "D");
//					}
				}
				if ((userID >= 0 && userID < Config.userIdSize)) {
					getClickProb("U", userID, feature, prob);
//					String res = user.get(userID);
//					if (res != null) {
//						getMore(res, prob, "U");
//					}
				}

				// 1/(1+e^(log(B)-log(A));
				result.resultScore[index] = 1.0 / (1.0 + Math.exp(prob[1]
						- prob[0]));
				index++;

			}
			br.close();
			System.out.println("Id Naive Bayes test finished...");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 
	 * @return click probability
	 */
	public static void getClickProb(String flag, int value, IdFeatures feature,
			double[] prob) {
		if (flag.equals("Q")) {// QueryID
			getClick(feature.queryClick, feature.queryNotClick, value, prob,
					"queryID");
		} else if (flag.equals("T")) {// TitleID
			getClick(feature.titleClick, feature.titleNotClick, value, prob,
					"TitleID");
		} else if (flag.equals("P")) {// PurchaseID
			getClick(feature.purchaseClick, feature.purchaseNotClick, value,
					prob, "PurchaseID");
		} else if (flag.equals("D")) {// DescriptionID
			getClick(feature.descriptionClick, feature.descriptionNotClick,
					value, prob, "DescriptionID");
		} else if (flag.equals("U")) {// UserID
			getClick(feature.userClick, feature.userNotClick, value, prob,
					"UserID");

		} else if (flag.equals("A")) {// adID
			getClick(feature.adClick, feature.adNotClick, value, prob, "AdID");

		} else if (flag.equals("Aer")) {// advertiserID
			getClick(feature.advertiserClick, feature.advertiserNotClick,
					value, prob, "AerID");

		}
	}

	private static void getMore(String str, double[] prob, String flag)
			throws IOException, ClassNotFoundException {
		// TODO Auto-generated method stub
		String[] sp = str.split("\\|");
		if (flag.equals("U")) {
			int gender = Integer.parseInt(sp[0]);
			int age = Integer.parseInt(sp[1]);
			getClick(featureNB.genderClick, featureNB.genderNotClick, gender,
					prob, "Gender");
			getClick(featureNB.ageClick, featureNB.ageNotClick, age, prob,
					"Age");
		} else if (flag.equals("Q")) {
			for (int i = 0; i < sp.length; i++) {
				int token = Integer.parseInt(sp[i]);
				getClick(featureNB.queryClick, featureNB.queryNotClick, token,
						prob, "query");
			}
		} else if (flag.equals("D")) {
			for (int i = 0; i < sp.length; i++) {
				int token = Integer.parseInt(sp[i]);
				getClick(featureNB.descriptionClick, featureNB.descriptionNotClick, token,
						prob, "description");
			}
		}

	}

	private static void getClick(double[] queryClick, double[] queryNotClick,
			int value, double[] prob, String flag) {

		if (queryClick[value] != -1) {// -1 is NOVALUE
			prob[0] += Math.log(queryClick[value]);
		}// else {
			// System.out.println(flag + "\t" + "Click" + "\t"+value);
		// }
		if (queryNotClick[value] != -1) {// -1 is NOVALUE
			prob[1] += Math.log(queryNotClick[value]);
		} // else {
			// System.out.println(flag + "\t" + "unClick" + "\t"+value);
		// }

	}

}
